#include "ONB.h"

//Default constructor
ONB::ONB()
{
	u = v = w = Vector3(0.0f, 0.0f, 0.0f);
}

//Initialization constructor
ONB::ONB(const Vector3& a, const Vector3& b, const Vector3& c)
{
	//assuming all are orthonormal
	u = a;
	v = b;
	w = c;
}

//construct from single vectors
//Construct from U
void ONB::ConstructFromU(const Vector3& parallel_u)
{
	//normalize u
	u = parallel_u.GetNormalizedVector();
	//two temp vectors
	Vector3 t1(1.0f, 0.0f, 0.0f), t2(0.0f, 1.0f, 0.0f);
	v = u ^ t1;
	if(v*v < 0.01f)		//abs length
		v = u ^ t2;
	w = u ^ v;		//find third vector
}

//construct from V
void ONB::ConstructFromV(const Vector3& parallel_v)
{
	//normalize v
	v = parallel_v.GetNormalizedVector();
	//two temp vectors
	Vector3 t1(1.0f, 0.0f, 0.0f), t2(0.0f, 1.0f, 0.0f);
	w = v ^ t1;
	if(w*w < 0.01f)		//abs length
		w = v ^ t2;
	u = v ^ w;		//find third vector
}

void ONB::ConstructFromW(const Vector3& parallel_w)
{
	//normalize w
	w = parallel_w.GetNormalizedVector();
	//two temp vectors
	Vector3 t1(1.0f, 0.0f, 0.0f), t2(0.0f, 1.0f, 0.0f);
	u = w ^ t1;
	if(u*u < 0.01f)		//abs length
		u = w ^ t2;
	v = w ^ u;		//find third vector
}

//Construct from dual vectors
//parallel to one vector
void ONB::ConstructFromUV(const Vector3& parallel_u, const Vector3& _v)
{
	//normalize u
	u = parallel_u.GetNormalizedVector();
	w = (u ^ _v).GetNormalizedVector();		//get new v perp to both parallel_u and _v;
	v = w ^ u;
}

void ONB::ConstructFromVU(const Vector3& parallel_v, const Vector3& _u)
{
	//normalize v
	v = parallel_v.GetNormalizedVector();
	w = (_u ^ v).GetNormalizedVector();
	u = v ^ w;
}

void ONB::ConstructFromWV(const Vector3& parallel_w, const Vector3& _v)
{
	//normalize u
	w = parallel_w.GetNormalizedVector();
	u = (_v ^ w).GetNormalizedVector();		//get new v perp to both parallel_u and _v;
	v = w ^ u;
}

void ONB::ConstructFromVW(const Vector3& parallel_v, const Vector3& _w)
{
	//normalize v
	v = parallel_v.GetNormalizedVector();
	u = (v ^ _w).GetNormalizedVector();
	w = u ^ v;
}

void ONB::ConstructFromUW(const Vector3& parallel_u, const Vector3& _w)
{
	//normalize u
	u = parallel_u.GetNormalizedVector();
	v = (_w ^ u).GetNormalizedVector();		//get new v perp to both parallel_u and _v;
	w = u ^ v;
}

void ONB::ConstructFromWU(const Vector3& parallel_w, const Vector3& _u)
{
	//normalize v
	w = parallel_w.GetNormalizedVector();
	v = (w ^ _u).GetNormalizedVector();
	u = v ^ w;
}








